<?php
namespace common\models;

use common\base\BaseActiveRecord;
use common\helpers\TStringHelper;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\debug\components\search\matchers\Base;
use yii\web\IdentityInterface;
use yii\base\Exception;

/**
 * This is the model class for table "{{%user}}".
 *
 * @property integer $id
 * @property string $username
 * @property string $nickname
 * @property string $avatar
 * @property string $realname
 * @property string $mobile
 * @property integer $is_mobile_verify
 * @property string $email
 * @property integer $is_email_verify
 * @property string $signature
 * @property string $city
 * @property string $address
 * @property string $follow_industry
 * @property string $password_reset_token
 * @property string $auth_key
 * @property string $password_hash
 * @property double $credit
 * @property integer $safety_score
 * @property integer $integral
 * @property integer $role
 * @property integer $login_number
 * @property string $last_time
 * @property integer $status
 * @property integer $version
 * @property string $created_by
 * @property integer $created_at
 * @property string $created_from
 * @property string $created_ip
 * @property string $updated_by
 * @property integer $updated_at
 * @property string $updated_from
 * @property string $updated_ip
 * @property integer $is_deleted
 * @property string $password write-only password
 */
class User extends BaseActiveRecord implements IdentityInterface
{

    const USER_ROLE_NORMAL = 10; //普通用户
    const USER_ROLE_MODIFYER = 2; //编辑用户
    const USER_ROLE_MANAGER = 1; //管理员

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%user}}';
    }

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            TimestampBehavior::className(),
        ];
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['username', 'email', 'auth_key', 'password_hash', 'created_by', 'created_at'], 'required'],
            [['is_mobile_verify', 'is_email_verify', 'integral', 'role', 'login_number', 'status', 'version', 'created_at', 'updated_at', 'is_deleted','safety_score'], 'integer'],
            [['credit'], 'number'],
            [['last_time'], 'safe'],
            [['username', 'realname', 'created_by', 'created_from', 'created_ip', 'updated_by', 'updated_from', 'updated_ip'], 'string', 'max' => 50],
            [['nickname', 'signature', 'city'], 'string', 'max' => 100],
            [['avatar', 'email', 'address', 'follow_industry', 'password_reset_token', 'password_hash'], 'string', 'max' => 255],
            [['mobile'], 'string', 'max' => 11],
            [['auth_key'], 'string', 'max' => 32],
            ['status', 'default', 'value' => self::STATUS_FLAG_NORMAL],
            ['status', 'in', 'range' => [self::STATUS_FLAG_TEMP, self::STATUS_FLAG_NORMAL, self::STATUS_FLAG_STOP]],
            ['is_deleted', 'default', 'value' => self::DELETE_FLAG_NO],
            ['is_deleted', 'in', 'range' => [self::DELETE_FLAG_NO, self::DELETE_FLAG_YES]],
        ];
    }

    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['create'] = ['username', 'password_hash', 'email', 'role'];
        $scenarios['update'] = ['username', 'email', 'role'];
        return $scenarios;
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('common', 'id'),
            'username' => Yii::t('common', 'username'),
            'nickname' => Yii::t('common', 'nickname'),
            'avatar' => Yii::t('common', 'avatar'),
            'realname' => Yii::t('common', 'realname'),
            'mobile' => Yii::t('common', 'mobile'),
            'is_mobile_verify' => Yii::t('common', 'is_mobile_verify'),
            'email' => Yii::t('common', 'email'),
            'is_email_verify' => Yii::t('common', 'is_email_verify'),
            'signature' => Yii::t('common', 'signature'),
            'city' => Yii::t('common', 'city'),
            'address' => Yii::t('common', 'address'),
            'follow_industry' => Yii::t('common', 'follow_industry'),
            'password_reset_token' => Yii::t('common', 'password_reset_token'),
            'auth_key' => Yii::t('common', 'auth_key'),
            'password_hash' => Yii::t('common', 'password_hash'),
            'safety_score' => Yii::t('common', 'safety_score'),
            'credit' => Yii::t('common', 'credit'),
            'integral' => Yii::t('common', 'integral'),
            'role' => Yii::t('common', 'role'),
            'login_number' => Yii::t('common', 'login_number'),
            'last_time' => Yii::t('common', 'last_time'),
            'status' => Yii::t('common', 'status'),
            'version' => Yii::t('common', 'version'),
            'created_by' => Yii::t('common', 'created_by'),
            'created_at' => Yii::t('common', 'created_at'),
            'created_from' => Yii::t('common', 'created_from'),
            'created_ip' => Yii::t('common', 'created_ip'),
            'updated_by' => Yii::t('common', 'updated_by'),
            'updated_at' => Yii::t('common', 'updated_at'),
            'updated_from' => Yii::t('common', 'updated_from'),
            'updated_ip' => Yii::t('common', 'updated_ip'),
            'is_deleted' => Yii::t('common', 'is_deleted'),
        ];
    }

    /**
     * @inheritdoc
     */
    public static function findIdentity($id)
    {
        return static::findOne(['id' => $id]);
    }

    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    }

    /**
     * Finds user by username
     *
     * @param string $username
     * @return static|null
     */
    public static function findByUsername($username)
    {
        return static::findOne(['username' => $username]);
    }

    /**
     * Finds user by password reset token
     *
     * @param string $token password reset token
     * @return static|null
     */
    public static function findByPasswordResetToken($token)
    {
        if (!static::isPasswordResetTokenValid($token)) {
            return null;
        }

        return static::findOne([
            'password_reset_token' => $token
        ]);
    }

    /**
     * Finds out if password reset token is valid
     *
     * @param string $token password reset token
     * @return boolean
     */
    public static function isPasswordResetTokenValid($token)
    {
        if (empty($token)) {
            return false;
        }

        $timestamp = (int) substr($token, strrpos($token, '_') + 1);
        $expire = Yii::$app->params['user.passwordResetTokenExpire'];
        return $timestamp + $expire >= time();
    }

    /**
     * @inheritdoc
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey()
    {
        return $this->auth_key;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey)
    {
        return $this->getAuthKey() === $authKey;
    }

    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return boolean if password provided is valid for current user
     */
    public function validatePassword($password)
    {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    /**
     * Generates password hash from password and sets it to the model
     *
     * @param string $password
     */
    public function setPassword($password)
    {
        $this->password_hash = Yii::$app->security->generatePasswordHash($password);
    }

    /**
     * Generates "remember me" authentication key
     */
    public function generateAuthKey()
    {
        $this->auth_key = Yii::$app->security->generateRandomString();
    }

    /**
     * Generates new password reset token
     */
    public function generatePasswordResetToken()
    {
        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
    }

    /**
     * Removes password reset token
     */
    public function removePasswordResetToken()
    {
        $this->password_reset_token = null;
    }

    /**
     * 返回用户名
     * @param $userId
     * @return null|string
     */
    public static function getUsernameByUid($userId) {
        $model = User::findOne($userId);
        return $model ? $model->username : null;
    }

    /**
     * @param $data
     * @return bool
     * @throws Exception
     * 用户注册
     */
    public function register($data)
    {
        if (empty($data['username'])) {
            return ['code' => -1, 'data' => [], 'msg' => '用户名不能为空'];
        }
        if (!TStringHelper::check_username($data['username'])) {
            return ['code' => -1, 'data' => [], 'msg' => '用户名不合法'];
        }

        if (!isset($data['mobile']) || empty($data['mobile'])) {
            return ['code' => -1, 'data' => [], 'msg' => '手机号码不能为空!'];
        }

        //验证短信验证码
        if (!isset($data['captcha']) || empty($data['captcha'])) {
            return ['code' => -1, 'data' => [], 'msg' => '手机验证码不能为空'];
        }

        //验证短信验证码
        $captcha = Yii::$app->session->get('reg_'.$data['mobile']);
        if ($captcha != $data['captcha']) {
            return ['code' => -1, 'data' => [], 'msg' => '短信验证码错误!'];
        }

        if (!isset($data['password']) || empty($data['password'])) {
            return ['code' => -1, 'data' => [], 'msg' => '密码不能为空'];
        }

        if ($data['password'] !== $data['repassword']) {
            return ['code' => -1, 'data' => [], 'msg' => '两次密码输入不一致'];
        }

        if (TStringHelper::CheckPasswordStrength($data['password']) < 2) {
            return ['code' => -1, 'data' => [], 'msg' => '输入密码过于简单'];
        }

        if (!isset($data['realname']) || empty($data['realname'])) {
            return ['code' => -1, 'data' => [], 'msg' => '真实姓名不能为空'];
        }

        if (!isset($data['email']) || empty($data['email'])) {
            return ['code' => -1, 'data' => [], 'msg' => '用户邮箱不能为空'];
        }

        //验证邮箱，电话号码，用户名是否被注册过
        if (static::find()->where("username='{$data['username']}' OR email='{$data['email']}' OR mobile='{$data['mobile']}'")->exists()) {
            return ['code' => -1, 'data' => [], 'msg' => '该用户已经注册过'];
        }
        $datas['_csrf'] = $data['_csrf'];
        $loaddata['username'] = $data['username'];
        $loaddata['password_hash'] = Yii::$app->security->generatePasswordHash($data['password']);
        $loaddata['mobile'] = $data['mobile'];
        $loaddata['is_mobile_verify'] = 1;//手机已验证
        $loaddata['email'] = $data['email'];
        $loaddata['realname'] = $data['realname'];
        $loaddata['auth_key'] = Yii::$app->security->generateRandomString();
        $loaddata['created_at'] = time();
        $loaddata['created_by'] = 0;
        $loaddata['safety_score'] = TStringHelper::CheckPasswordStrength($data['password']);
        $datas['User'] = $loaddata;
        $this->load($datas);

        if ($this->save() === false) {
            return ['code' => -1, 'data' => [], 'msg' => '用户注册失败，请稍后重试'];
        }
        //用户注册成功后清除session中的短信验证码
        Yii::$app->session->remove('reg_'.$data['mobile']);
        return ['code' => 0, 'data' => $this->id, 'msg' => 'ok'];
    }


    /**
     * Finds user by username
     *
     * @param string $info
     * @return static|null
     */
    public static function findByUserinfo($info)
    {
        return static::find()->where('username=:info or mobile =:info or email = :info',[":info"=>$info])->one();
    }
}
